/**
 * @file 	 sq880.h
 * @brief                   
 * @author 	 wenbo
 * @version  1.0
 * @date 	 2022-02-11
 * 
 * @copyright Copyright (c) 2022  YGL
 * 
 */

#ifndef __SQ880_H
#define __SQ880_H

#include "../../bsp/bsp.h"


#define ADDR_RUN_MODE       0x0001      //F00.01 运行指令通道
#define ADDR_A_FREQ_SRC     0x0006      //F00.06 A 频率指令选择
#define ADDR_ACC_TIME       0x000C      //F00.12 加速时间
#define ADDR_DEC_TIME       0x000D      //F00.13 减速时间
#define ADDR_DI_S1_FUN      0x0401      //F04.01 S1端子功能选择
#define ADDR_DI_S2_FUN      0x0402      //F04.02 S2端子功能选择
#define ADDR_DI_S3_FUN      0x0403      //F04.03 S3端子功能选择
#define ADDR_DI_S4_FUN      0x0404      //F04.04 S4端子功能选择
#define ADDR_DI_S5_FUN      0x0405      //F04.05 S5端子功能选择
#define ADDR_CTRL_REG       0x2000      //特殊寄存器 控制字寄存器
#define ADDR_TAR_FREQ       0x3000      //特殊寄存器 设定频率 (unit:0.01Hz)
#define ADDR_STATE          0x6000      //特殊寄存器 状态寄存器1
#define ADDR_ERROR_CODE     0x6002      //特殊寄存器 故障代码
#define ADDR_CURRENT        0x0D06      //转矩电流


#define ADDR_STAGE_BASE     (0x0A00 + 2)
#define ADDR_STAGE_SPEED_0  (ADDR_STAGE_BASE + 0)       //段速0
#define ADDR_STAGE_SPEED_1  (ADDR_STAGE_BASE + 2)       //段速1
#define ADDR_STAGE_SPEED_2  (ADDR_STAGE_BASE + 4)       //段速2
#define ADDR_STAGE_SPEED_3  (ADDR_STAGE_BASE + 6)       //段速3
#define ADDR_STAGE_SPEED_4  (ADDR_STAGE_BASE + 8)       //段速4
#define ADDR_STAGE_SPEED_5  (ADDR_STAGE_BASE + 10)      //段速5
#define ADDR_STAGE_SPEED_6  (ADDR_STAGE_BASE + 12)      //段速6
#define ADDR_STAGE_SPEED_7  (ADDR_STAGE_BASE + 14)      //段速7
#define ADDR_STAGE_SPEED_8  (ADDR_STAGE_BASE + 16)      //段速8
#define ADDR_STAGE_SPEED_9  (ADDR_STAGE_BASE + 18)      //段速9
#define ADDR_STAGE_SPEED_10 (ADDR_STAGE_BASE + 20)      //段速10
#define ADDR_STAGE_SPEED_11 (ADDR_STAGE_BASE + 22)      //段速11
#define ADDR_STAGE_SPEED_12 (ADDR_STAGE_BASE + 24)      //段速12
#define ADDR_STAGE_SPEED_13 (ADDR_STAGE_BASE + 26)      //段速13
#define ADDR_STAGE_SPEED_14 (ADDR_STAGE_BASE + 28)      //段速14
#define ADDR_STAGE_SPEED_15 (ADDR_STAGE_BASE + 30)      //段速15


// F00.01 运行指令通道
typedef enum{
    MODE_KEY = 0,   // 0：键盘运行指令通道（LED熄灭）  
    MODE_IO,        // 1：端子运行指令通道（LED点亮）
    MODE_485,       // 2：通讯运行指令通道（LED闪烁）

    MODE_MAX,
}Type_sq880_Mode_Enum;

// F00.01 运行指令通道
typedef enum{
    STA_NONE = 0,   //0: 无效
    STA_FWD,        //1：正转运行中
    STA_REV,        //2：反转运行中
    STA_STOP,       //3：变频器停机中
    STA_FAULT,      //4：变频器故障中
    STA_OFF,        //5：变频器 P.oFF 状态

    STA_MAX,
}Type_sq880_State_Enum;

typedef enum{
    DI_FUN_NONE = 0,    // 0: 无功能 
    DI_FUN_FWD,         // 1: 正转运行
    DI_FUN_REV,         // 2: 反转运行 
    DI_FUN_3LINE,       // 3: 三线式运行控制
    DI_FUN_JOG_F,       // 4: 正转点动 
    DI_FUN_JOG_R,       // 5: 反转点动
    DI_FUN_FREE_STOP,   // 6: 自由停车 
    DI_FUN_RECOVER,     // 7: 故障复位
    DI_FUN_PAUSE,       // 8: 运行暂停 
    DI_FUN_EERR_IN,     // 9: 外部故障输入
    DI_FUN_FREQ_U,      // 10: 频率设定递增（UP） 
    DI_FUN_FREQ_D,      // 11: 频率设定递减（DOWN）
    DI_FUN_FREQ_CLR,    // 12: 频率增减设定清除 
    DI_FUN_SWITCH_AB,   // 13: A 设定与 B 设定切换
    DI_FUN_SWITCH_A,    // 14: 组合设定与 A 设定切换 
    DI_FUN_SWITCH_B,    // 15: 组合设定与 B 设定切换
    DI_FUN_STAGE_1,     // 16: 多段速端子 1 
    DI_FUN_STAGE_2,     // 17: 多段速端子 2
    DI_FUN_STAGE_3,     // 18: 多段速端子 3 
    DI_FUN_STAGE_4,     // 19: 多段速端子 4
    DI_FUN_STAGE_PAUSE, // 20: 多段速暂停 
    DI_FUN_ACC_TIM1,    // 21: 加减速时间选择 1
    DI_FUN_ACC_TIM2,    // 22: 加减速时间选择 2 
    DI_FUN_RESERV1,     // 23: 保留
    DI_FUN_RESERV2,     // 24: 保留 
    DI_FUN_PID_PAUSE,   // 25: PID 控制暂停
    DI_FUN_RESERV3,     // 26: 保留 
    DI_FUN_RESERV4,     // 27: 保留
    DI_FUN_CNT_RESET,   // 28: 计数器复位 
    DI_FUN_RESERV5,     // 29: 保留
    DI_FUN_NO_ACC_DEC,  // 30: 加减速禁止 
    DI_FUN_RESERV6,     // 31: 保留
    DI_FUN_RESERV7,     // 32: 保留 
    DI_FUN_FREQ_CLR_P,  // 33: 频率增减设定暂时清除
    DI_FUN_BRAKE,       // 34: 直流制动 
    DI_FUN_RESERV8,     // 35: 保留
    DI_FUN_CMD_KEY,     // 36: 命令切换到键盘 
    DI_FUN_CMD_IO,      // 37: 命令切换到端子
    DI_FUN_CMD_485,     // 38: 命令切换到通讯

    DI_FUN_MAX,
}Type_sq880_DI_Fun_Enum;

// F00.06 A 频率指令选择
typedef enum{
    A_SRC_KEY = 0,  // 0：键盘数字设定
    A_SRC_KNOB,     // 1：面板电位器设定
    A_SRC_AI1,      // 2：模拟量AI1设定
    A_SRC_HDI,      // 3：高速脉冲HDI设定
    A_SRC_PLC,      // 4：简易PLC程序设定
    A_SRC_STAGE,    // 5：多段速运行设定
    A_SRC_PID,      // 6：PID控制设定
    A_SRC_MODBUS,   // 7：MODBUS 通讯设定

    A_SRC_MAX,
}Type_sq880_A_Src_Enum;

// ctrl 特殊寄存器 控制字寄存器
typedef enum{
    CTRL_NONE = 0,  // 0：无效
    CTRL_FWD,       // 1：正转运行
    CTRL_REV,       // 2：反转运行
    CTRL_JOG_F,     // 3：正转点动
    CTRL_JOG_R,     // 4：反转点动
    CTRL_SLOW_STOP, // 5：减速停机
    CTRL_FREE_STOP, // 6：自由停机（紧急停机）
    CTRL_RECOVER,   // 7：故障复位
    CTRL_JOG_STOP,  // 8：点动停止

    CTRL_MAX,
}Type_sq880_Ctrl_Enum;

// error type 故障类型
typedef enum{
    ERR_NONE = 0,   // 0：无故障
    ERR_OVP_U,      // 1：加速过电压
    ERR_OVP_D,      // 2：减速过电压
    ERR_OVP_C,      // 3：恒速过电压
    ERR_OCP_U,      // 4：加速过电流
    ERR_OCP_D,      // 5：减速过电流
    ERR_OCP_C,      // 6：恒速过电流
    ERR_UVP,        // 7：母线欠压故障
    ERR_OLP_1,      // 8：电机过载
    ERR_OLP_2,      // 9：变频器过载
    ERR_SPo,        // 10：输出侧缺相
    ERR_OTP,        // 11：逆变模块过热故障
    ERR_EXT,        // 12：外部故障
    ERR_485,        // 13：485通讯故障
    ERR_IcE,        // 14：电流检测故障
    ERR_EEP,        // 15：EEPROM操作故障
    ERR_PID,        // 16：PID反馈断线故障
    ERR_TUE,        // 17：参数自学习故障

    ERR_MAX,
}Type_sq880_Err_Enum;

// 485通信相关
typedef struct{
	uint8_t 	slave_id;    		    //modbus slave id
	uint8_t 	port;    			    //modbus uart port
    uint32_t 	speed;   			    //modbus uart speed
    uint8_t 	rec_data[20];    	    //modbus recive buffer
    uint8_t 	rec_len; 			    //modbus recive data length
}Type_sq880_Com_Def;

// SQ880 结构
typedef struct
{
    bool            isInitOk;
    bool            isReverseDir;

    // comm
	Type_sq880_Com_Def 	    com;

    // registor
	Type_sq880_Mode_Enum    mode;
    Type_sq880_A_Src_Enum   A_src;
    Type_sq880_Ctrl_Enum    ctrl;
    Type_sq880_Err_Enum     errCode;
    Type_sq880_State_Enum   state;

    int16_t         stageTable[16];
    int16_t         current;
    int16_t         tar_freq;
    uint16_t        accTime;
    uint16_t        decTime;

    // io
    Type_GPIO_Def   gpio_STF;
    Type_GPIO_Def   gpio_STR;
    Type_GPIO_Def   gpio_S0;
    Type_GPIO_Def   gpio_S1;
    Type_GPIO_Def   gpio_S2;      

}Type_sq880_Def;

/************************************************************************/
/**
 * @brief       初始化速驱变频器
 * @param[in]	pList               变频器列表
 * @param[in]	listLen             变频器列表长度
 * @return      bool                执行成功返回true
 */
extern bool xp_sq880_init(Type_sq880_Def * const pList, uint8_t listLen);

/**
 * @brief       驱动卸载
 * @return      bool                执行成功返回true
 */
extern bool xp_sq880_Deinit(void);



/************************************************************************/
/**
 * @brief       通过总线控制变频器运行
 * @param[in]	devId               变频器序号
 * @param[in]	freq                目标频率(0：减速停止，单位0.01Hz)
 * @return      bool                执行成功返回true
 */
extern bool xp_sq880_bus_run(int devId, int freq);

/**
 * @brief       通过IO控制变频器运行(会自动切换到IO控制模式)
 * @param[in]	devId               变频器序号
 * @param[in]	speed               段速(0：停止，-7 ~ 7)
 * @return      bool                执行成功返回true
 */
extern bool xp_sq880_io_run(uint8_t devId, int speed);



/************************************************************************/
/**
 * @brief       获取变频器错误码
 * @param[in]	devId               变频器序号
 * @param[out]	pResult             错误码结果
 * @return      bool                执行成功返回true
 */
extern bool xp_sq880_get_error_code(int devId, uint32_t *pResult);

/**
 * @brief       获取变频器电流
 * @param[in]	devId               变频器序号
 * @param[out]	pResult             电流结果
 * @return      bool                执行成功返回true
 */
extern bool xp_sq880_get_current(int devId, int16_t *pResult);

/**
 * @brief       获取变频器状态
 * @param[in]	devId               变频器序号
 * @param[out]	pResult             状态结果
 * @return      bool                执行成功返回true
 */
bool xp_sq880_get_state(int devId, uint16_t *pResult);



/************************************************************************/
/**
 * @brief       清除驱动器错误
 * @param[in]	devId               变频器序号
 * @return      bool                执行成功返回true
 */
extern bool xp_sq880_clear_error(int devId);

/**
 * @brief       设置指定索引的段速值
 * @param[in]	devId               变频器索引id
 * @param[in]	stage_id            段速id
 * @param[in]	val                 段速目标值(单位0.01Hz)          
 * @return      bool                执行成功返回true
 */
extern bool xp_sq880_set_stage_speed(int devId, uint8_t stage_id, uint16_t val);

/**
 * @brief       设置指定索引的加速时间
 * @param[in]	devId               变频器索引id
 * @param[in]	time                加速时间（单位0.1s）
 * @return      bool                执行成功返回true
 */
extern bool xp_sq880_set_acc_time(int devId, uint16_t val);

/**
 * @brief       设置指定索引的减速时间
 * @param[in]	devId               变频器索引id
 * @param[in]	time                减速时间（单位0.1s）
 * @return      bool                执行成功返回true
 */
extern bool xp_sq880_set_dec_time(int devId, uint16_t val);

#endif